home *** CD-ROM | disk | FTP | other *** search
- ; This is an example of an active TSR that counts keyboard interrupts
- ; once activated.
-
- ; The resident segment definitions must come before everything else.
-
- ResidentSeg segment para public 'Resident'
- ResidentSeg ends
-
- EndResident segment para public 'EndRes'
- EndResident ends
-
- .xlist
- include stdlib.a
- includelib stdlib.lib
- .list
-
-
- ; Resident segment that holds the TSR code:
-
- ResidentSeg segment para public 'Resident'
- assume cs:ResidentSeg, ds:nothing
-
- ; The following variable counts the number of keyboard interrupts
-
- KeyIntCnt word 0
-
- ; These two variables contain the original INT 9 and INT 16h
- ; interrupt vector values:
-
- OldInt9 dword ?
- OldInt16 dword ?
-
-
- ; MyInt9- The system calls this routine every time a keyboard
- ; interrupt occus. This routine increments the
- ; KeyIntCnt variable and then passes control on to the
- ; original Int9 handler.
-
- MyInt9 proc far
- inc ResidentSeg:KeyIntCnt
- jmp ResidentSeg:OldInt9
- MyInt9 endp
-
-
-
-
- ; MyInt16- This is the passive component of this TSR. An
- ; application explicitly calls this routine with an
- ; INT 16h instruction. If AH contains 0FFh, this
- ; routine returns the number of keyboard interrupts
- ; in the AX register. If AH contains any other value,
- ; this routine passes control to the original INT 16h
- ; (keyboard trap) handler.
-
- MyInt16 proc far
- cmp ah, 0FFh
- je ReturnCnt
- jmp ResidentSeg:OldInt16 ;Call original handler.
-
- ; If AH=0FFh, return the keyboard interrupt count
-
- ReturnCnt: mov ax, ResidentSeg:KeyIntCnt
- iret
- MyInt16 endp
-
-
- ResidentSeg ends
-
-
-
- cseg segment para public 'code'
- assume cs:cseg, ds:ResidentSeg
-
- Main proc
- meminit
-
- mov ax, ResidentSeg
- mov ds, ax
- mov ax, 0
- mov es, ax
-
- print
- byte "Keyboard interrupt counter TSR program",cr,lf
- byte "Installing....",cr,lf,0
-
- ; Patch into the INT 9 and INT 16 interrupt vectors. Note that the
- ; statements above have made ResidentSeg the current data segment,
- ; so we can store the old INT 9 and INT 16 values directly into
- ; the OldInt9 and OldInt16 variables.
-
- cli ;Turn off interrupts!
- mov ax, es:[9*4]
- mov word ptr OldInt9, ax
- mov ax, es:[9*4 + 2]
- mov word ptr OldInt9+2, ax
- mov es:[9*4], offset MyInt9
- mov es:[9*4+2], seg ResidentSeg
-
- mov ax, es:[16h*4]
- mov word ptr OldInt16, ax
- mov ax, es:[16h*4 + 2]
- mov word ptr OldInt16+2, ax
- mov es:[16h*4], offset MyInt16
- mov es:[16h*4+2], seg ResidentSeg
- sti ;Okay, ints back on.
-
- ; We're hooked up, the only thing that remains is to terminate and
- ; stay resident.
-
- print
- byte "Installed.",cr,lf,0
-
- mov ah, 62h ;Get this program's PSP
- int 21h ; value.
-
- mov dx, EndResident ;Compute size of program.
- sub dx, bx
- mov ax, 3100h ;DOS TSR command.
- int 21h
- Main endp
- cseg ends
-
- sseg segment para stack 'stack'
- stk db 1024 dup ("stack ")
- sseg ends
-
- zzzzzzseg segment para public 'zzzzzz'
- LastBytes db 16 dup (?)
- zzzzzzseg ends
- end Main
-